package com.gzhryc.net_marketing.cloud.business.services;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.gzhryc.common.json.JsonTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.jdbc.Conditions;
import com.gzhryc.jdbc.MultiDBTools;
import com.gzhryc.net_marketing.cloud.business.dao.UserPayGoodsOrderLogDao;
import com.gzhryc.net_marketing.cloud.business.dao.db.UserPayGoodsOrderLog;
import com.gzhryc.net_marketing.cloud.business.dao.enums.PayGoodsOrderLogEnum;
import com.gzhryc.net_marketing.cloud.business.services.models.PayGoodsOrderLogItem;

public class UserPayGoodsOrderLogService {

    static Logger log = Logger.getLogger(UserPayGoodsOrderLogService.class);

    public static UserPayGoodsOrderLogService self() {
        return MultiDBTools.getService(UserPayGoodsOrderLogService.class, true);
    }

    public static UserPayGoodsOrderLogService self(String jdbcKey) {
        return MultiDBTools.getService(jdbcKey, UserPayGoodsOrderLogService.class, true);
    }

    UserPayGoodsOrderLogDao dao;

    public UserPayGoodsOrderLogService(String jdbcKey) {
        dao = new UserPayGoodsOrderLogDao(jdbcKey);
    }

    public UserPayGoodsOrderLog getOrAddByTradeNo(String tradeNo, Date createDate) {
        if (StringUtils.isNotBlank(tradeNo)) {
            try {
            	UserPayGoodsOrderLog payOrderLog = dao.getById(tradeNo);
                if (payOrderLog != null) {
                    return payOrderLog;
                } else {
                	payOrderLog = new UserPayGoodsOrderLog();
                	payOrderLog.setTradeNo(tradeNo);
                	payOrderLog.setCreateDate(createDate);

                    if (dao.insert(payOrderLog) > 0) {
                        return payOrderLog;
                    }
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public boolean lockUpdate(String tradeNo) {
        if (StringUtils.isNotBlank(tradeNo)) {
            Conditions condition = new Conditions(UserPayGoodsOrderLog.class);
            condition.and().is("tradeNo", tradeNo);
            condition.and().is("lockState", PayGoodsOrderLogEnum.LockState.Open.index());

            Map<String, Object> data = new HashMap<>();
            data.put("lockState", PayGoodsOrderLogEnum.LockState.Close.index());

            try {
                return dao.update(data, condition) > 0;
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return false;
    }

    public boolean openUpdate(String tradeNo) {
        if (StringUtils.isNotBlank(tradeNo)) {
        	UserPayGoodsOrderLog updateEntity = new UserPayGoodsOrderLog();
            updateEntity.setTradeNo(tradeNo);
            updateEntity.setLockState(PayGoodsOrderLogEnum.LockState.Open.index());

            try {
                return dao.updateNotNull(updateEntity) > 0;
            } catch (SQLException e) {
                log.error(e.getMessage(), e);
            }
        }
        return false;
    }

    public boolean addItemList(UserPayGoodsOrderLog entity, List<PayGoodsOrderLogItem> itemList) {
        if (entity != null && itemList != null && itemList.size() > 0) {
            //进行锁定
            if (lockUpdate(entity.getTradeNo())) {
                boolean flag = true;
                try {
                    List currentItemList = null;
                    if (StringUtils.isNotBlank(entity.getLogsContent())) {
                        currentItemList = JsonTools.str2List(entity.getLogsContent());
                    } else {
                        currentItemList = new ArrayList<PayGoodsOrderLogItem>();
                    }
                    currentItemList.addAll(itemList);

                    String logsContent = JsonTools.toJson(currentItemList);

                    UserPayGoodsOrderLog updateEntity = new UserPayGoodsOrderLog();
                    updateEntity.setTradeNo(entity.getTradeNo());
                    updateEntity.setLogsContent(logsContent);
                    updateEntity.setLockState(PayGoodsOrderLogEnum.LockState.Open.index());

                    try {
                        if (this.dao.updateNotNull(updateEntity) > 0) {
                            flag = false;
                            return true;
                        }
                    } catch (SQLException e) {
                        log.error(e.getMessage(), e);
                    }
                } finally {
                    if (flag) {
                        openUpdate(entity.getTradeNo());
                    }
                }
            }
        }
        return false;
    }

    public boolean addItem(String tradeNo, PayGoodsOrderLogItem item) {
    	UserPayGoodsOrderLog orderLog = getOrAddByTradeNo(tradeNo, new Date());
        if (orderLog != null) {
            //进行锁定
            if (lockUpdate(orderLog.getTradeNo())) {
                boolean flag = true;
                try {
                    List currentItemList = null;
                    if (StringUtils.isNotBlank(orderLog.getLogsContent())) {
                        currentItemList = JsonTools.str2List(orderLog.getLogsContent());
                    } else {
                        currentItemList = new ArrayList<PayGoodsOrderLogItem>();
                    }

                    currentItemList.add(item);
                    String logsContent = JsonTools.toJson(currentItemList);

                    UserPayGoodsOrderLog updateEntity = new UserPayGoodsOrderLog();
                    updateEntity.setTradeNo(orderLog.getTradeNo());
                    updateEntity.setLogsContent(logsContent);
                    updateEntity.setLockState(PayGoodsOrderLogEnum.LockState.Open.index());

                    try {
                        if (this.dao.updateNotNull(updateEntity) > 0) {
                            flag = false;
                            return true;
                        }
                    } catch (SQLException e) {
                        log.error(e.getMessage(), e);
                    }
                } finally {
                    if (flag) {
                        openUpdate(orderLog.getTradeNo());
                    }
                }
            }
        }
        return false;
    }
}
